<script setup lang="ts">
import { computed, onBeforeUnmount, ref, watch } from 'vue'
import type { LoginParams } from '../../types/user'
import { getCode } from '@/utils'
import { useUserStore } from '@/stores/user'
import { useRouter } from 'vue-router'
import agconnect from '@hw-agconnect/api'
import { ElMessage } from 'element-plus'
import { credentialWithPassword, credentialWithVerifyCode, getPhoneCode } from '@/utils/login_phone'
import { createUser } from '@/AGC/utils/user'

// 登录方式
const loginMethods = ref('password')
// 监听登录方式
watch(
  () => loginMethods.value,
  () => {
    formModel.value = { phone: '', password: '', code: '' }
    formRef.value.clearValidate()
  },
)
const router = useRouter()
const userStore = useUserStore()
const formRef = ref()
const formModel = ref<LoginParams>({
  phone: '',
  password: '',
  code: '',
})
// 随机生成的验证码
const code = ref(getCode())
const rules = {
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    {
      validator: (rule: unknown, value: string, callback: (err?: Error) => void) => {
        // 对value进行校验，此时的value就是form.mobile
        if (/^1[3-9]\d{9}$/.test(value)) {
          // 通过
          callback()
        } else {
          callback(new Error('手机号格式不对'))
        }
      },
      trigger: 'blur',
    },
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    {
      pattern:
        /^(?:(?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*\d)|(?=.*[a-z])(?=.*[^a-zA-Z\d])|(?=.*[A-Z])(?=.*\d)|(?=.*[A-Z])(?=.*[^a-zA-Z\d])|(?=.*\d)(?=.*[^a-zA-Z\d])).{8,}$/,
      max: 20,
      message: '密码长度至少为8位且至少包含两种字符类型（大写字母、小写字母、数字、符号）',
      trigger: 'blur',
    },
  ],
  code: [
    { required: true, message: '请输入验证码', trigger: 'blur' },
    {
      validator: (rule: unknown, value: string, callback: (err?: Error) => void) => {
        if (loginMethods.value == 'password') {
          if (value.toLowerCase() == code.value.toLowerCase()) {
            callback()
          } else {
            callback(new Error('验证码不正确'))
          }
        } else {
          callback()
        }
      },
      trigger: 'blur',
    },
  ],
}
// 密码登录
const login = async () => {
  // 1. 校验
  await formRef.value.validate()
  // 2. 获取 AGC的用户信息
  const res = await agconnect.auth().getCurrentUser()

  if (res) {
    // 用户已经登陆
    const token = formModel.value.phone
    userStore.setToken(token)
    router.replace('/')
  } else {
    // 用户未登录
    // 获取登录结果
    const { phone, password } = { ...formModel.value }
    const signInResult = await credentialWithPassword(phone, password)

    if (signInResult) {
      // 登录成功 => 保存 token
      ElMessage.success('登录成功')
      // const token = (await signInResult.getUser().getToken(true)).getToken().slice(100, 200)
      // userStore.setToken(token)
      userStore.setToken(phone)
      router.replace('/')
    } else {
      ElMessage.error('手机号或密码错误')
    }
  }
}
// 倒计时
const countdown = ref(60)
// 倒计时定时器
let timer: number | undefined = undefined
// 开启定时器
const startCountdown = () => {
  countdown.value--
  timer = setInterval(() => {
    if (countdown.value > 1) {
      countdown.value--
    } else {
      clearInterval(timer)
      countdown.value = 60
      formModel.value.code = ''
    }
  }, 1000)
}
// 验证码字段描述
const codeDesc = computed(() => {
  return countdown.value > 59 ? '获取验证码' : `重发验证码(${countdown.value}s)`
})
// 获取手机验证码
const sendCode = async () => {
  await formRef.value.validateField('phone')
  // 开启倒计时
  startCountdown()
  // 发送验证码
  await getPhoneCode(formModel.value.phone)
}
// 短信登录
const loginByCode = async () => {
  // 1. 校验
  await formRef.value.validateField('phone')
  await formRef.value.validateField('code')
  // 2. 获取AGC用户信息
  const user = await agconnect.auth().getCurrentUser()

  if (user) {
    // 用户已经登录
    // const token = (await user.getToken(true)).getToken().slice(100, 200)
    // userStore.setToken(token)
    userStore.setToken(formModel.value.phone)
    router.replace('/')
  } else {
    // 用户未登录
    // 获取登录结果
    const { phone, code } = { ...formModel.value }
    const signInResult = await credentialWithVerifyCode(phone, code)

    if (signInResult) {
      // 登录成功，获取token
      ElMessage.success('登录成功')
      // const token = (await signInResult.getUser().getToken(true)).getToken()
      // // 保存 token
      // userStore.setToken(token.slice(100, 200))
      userStore.setToken(phone)
      // 创建用户
      await createUser(phone)
      // 3. 跳转
      router.replace('/')
    } else {
      ElMessage.error('手机号或验证码错误')
    }
  }
}
// 页面卸载前，销毁资源
onBeforeUnmount(() => {
  if (timer) clearInterval(timer)
})
</script>

<template>
  <div class="container">
    <!-- 白色卡片 -->
    <el-card>
      <!-- logo -->
      <div class="logo">
        <span :class="{ active: loginMethods == 'password' }" @click="loginMethods = 'password'">
          密码登录
        </span>
        |
        <span :class="{ active: loginMethods == 'code' }" @click="loginMethods = 'code'">
          短信登录
        </span>
      </div>
      <!-- 登录表单 -->
      <el-form ref="formRef" :model="formModel" :rules="rules" label-width="70px">
        <el-form-item prop="phone" label="手机号:">
          <el-input v-model="formModel.phone" placeholder="请输入手机号"></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item
          prop="password"
          label="密码:"
          style="margin: 30px 0"
          v-show="loginMethods == 'password'"
        >
          <el-input
            v-model="formModel.password"
            placeholder="请输入密码"
            type="password"
            show-password
          ></el-input>
        </el-form-item>
        <!-- 验证码：前端校验的 -->
        <el-form-item prop="code" label="验证码:" v-show="loginMethods == 'password'">
          <div style="display: flex; justify-content: space-between; width: 100%">
            <el-input
              v-model="formModel.code"
              placeholder="请输入验证码"
              style="width: 60%"
              @keyup.enter="login"
            ></el-input>
            <div class="code" @click="code = getCode()">{{ code }}</div>
          </div>
        </el-form-item>
        <!-- 验证码：手机号验证码 -->
        <el-form-item
          prop="code"
          label="验证码:"
          style="margin-top: 92px"
          v-show="loginMethods == 'code'"
        >
          <el-input
            v-model="formModel.code"
            placeholder="请输入校验码"
            style="width: 50%"
            @keyup.enter="loginByCode"
          ></el-input>
          <el-button
            type="text"
            @click="sendCode"
            :disabled="countdown < 60"
            style="margin-left: 5%"
          >
            {{ codeDesc }}
          </el-button>
        </el-form-item>
        <!-- 登录|注册 -->
        <el-form-item label="">
          <div style="display: flex; justify-content: space-between; width: 100%">
            <el-button
              type="primary"
              @click="login"
              style="width: 40%"
              v-if="loginMethods == 'password'"
              >登 录
            </el-button>
            <el-button type="primary" @click="loginByCode" style="width: 40%" v-else
              >登 录
            </el-button>
            <el-button type="primary" @click="$router.push('/register')" style="width: 40%"
              >去注 册</el-button
            >
          </div>
        </el-form-item>
        <el-form-item>
          <div style="display: flex; justify-content: end; width: 100%">
            <el-button type="text" @click="$router.push('/modify')">忘记密码?</el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<style scoped lang="less">
.container {
  position: absolute;
  width: 100%;
  height: 100%;
  background: url(../../assets/login.png) no-repeat center / cover;
  // 饿了么的组件解析后，组件根标签回加载一个和组件名称一致的类名
  .el-card {
    width: 440px;
    height: 360px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    .logo {
      width: 200px;
      height: 50px;
      display: block;
      text-align: center;
      line-height: 50px;
      margin: 0 auto 20px;

      span {
        cursor: pointer;
        &.active {
          color: rgb(245, 43, 0);
        }
      }
    }
    .el-form {
      padding: 0 20px;

      .code {
        width: 35%;
        height: 100%;
        background: url(../../assets/code_bg.png) no-repeat center / cover;
        text-align: center;
        letter-spacing: 10px;
        font-style: italic;
        padding-left: 4px;
        cursor: pointer;
      }
    }
  }
}
</style>
